#include "TimerMgr.h"

#include "TimeUtil.h"



CTimer::CTimer(char *pcsName, int iParam)
    :m_stName(pcsName), m_llCreateTimeStamp(0), m_llNextTriggerTimeStamp(0), m_eType(ENM_TIMER_ERROR),m_iParam(iParam)
{

}


CTimer::~CTimer()
{

}

int CTimer::Proc()
{
    return 0;
}

int64_t CTimerPreMilliSecond::GenerateNextTriggerTimeStamp()
{
    int64_t llNextTimeStamp = CTimeUtil::GetCurMilliSecond() + GetParam();

    return llNextTimeStamp;
}


int64_t CTimerPreSecond::GenerateNextTriggerTimeStamp()
{
    int64_t llNextTimeStamp = CTimeUtil::GetCurSecond() + GetParam();

    return llNextTimeStamp;
}

int64_t CTimerFixDayTime::GenerateNextTriggerTimeStamp()
{
    int64_t llThisTimeStamp = GetNextTriggerTimeStamp();
    int64_t llCurSecond = CTimeUtil::GetCurSecond();
    if (llThisTimeStamp > llCurSecond)
    {
        return llThisTimeStamp;
    }

    int64_t llFixTime = CTimeUtil::GetZeroInDay(llCurSecond) + GetParam();
    if (llFixTime > llCurSecond)
    {
        return llFixTime;
    }

    while (llFixTime <= llCurSecond)
    {
        llFixTime += 3600;
    }

    return llFixTime;
}


int64_t CTimerOnce::GenerateNextTriggerTimeStamp()
{
    return -1;
}


CTimerMgr::CTimerMgr()
{
}


CTimerMgr::~CTimerMgr()
{
}

bool CTimerMgr::Init()
{
    return true;
}

int CTimerMgr::Proc()
{
    static int64_t llPreTime = 0;
    int64_t llCurTime = CTimeUtil::GetCurSecond();
    int64_t llCurMilliTime = CTimeUtil::GetCurMilliSecond();

    //毫秒
    TimerVec::iterator vecIt = m_vecMilliSecondTimer.begin();
    for (; vecIt != m_vecMilliSecondTimer.end();)
    {
        CTimer *pTimer = *vecIt;
        if (pTimer == NULL)
        {
            vecIt = m_vecMilliSecondTimer.erase(vecIt);
            continue;
        }
        if (pTimer->GetDelFlag())
        {
            vecIt = m_vecMilliSecondTimer.erase(vecIt);
            continue;
        }

        int64_t llNextTrigger = pTimer->GenerateNextTriggerTimeStamp();
        if (llNextTrigger >= llCurMilliTime)
        {
            if ( pTimer->Proc() != 0 )
            {
                LOG_ERR("Timer Proc Faile. Timer:%s", pTimer->GetName().c_str());
            }
            pTimer->SetNextTriggerTimeStamp(llNextTrigger);
        }
        ++vecIt;
    }


    //秒
    if (llPreTime != llCurTime)
    {
        TimerVec::iterator vecIt = m_vecSecondTimer.begin();
        for (; vecIt != m_vecSecondTimer.end();)
        {
            CTimer *pTimer = *vecIt;
            if (pTimer == NULL)
            {
                vecIt = m_vecSecondTimer.erase(vecIt);
                continue;
            }
            if (pTimer->GetDelFlag())
            {
                vecIt = m_vecSecondTimer.erase(vecIt);
                continue;
            }

            int64_t llNextTrigger = pTimer->GetNextTriggerTimeStamp();
            if (llNextTrigger >= llCurMilliTime)
            {
                if (pTimer->Proc() != 0)
                {
                    LOG_ERR("Timer Proc Faile. Timer:%s", pTimer->GetName().c_str());
                }
                pTimer->SetNextTriggerTimeStamp(llNextTrigger);
            }
            ++vecIt;
        }
    }
    return 0;
}

int CTimerMgr::AddTimer(CTimer *pTimer)
{
    if (pTimer == NULL)
    {
        return -1;
    }

    if (pTimer->GetDelFlag())
    {
        return -1;
    }

    if (pTimer->GetType() == ENM_TIMER_PRE_MILLI_SECOND)
    {
        m_vecMilliSecondTimer.push_back(pTimer);
        LOG_INFO("add timer.name:%s, type:%d, param:%s", pTimer->GetName().c_str(), pTimer->GetType(), pTimer->GetParam());
    }

    return 0;
}

void CTimerMgr::Remove(CTimer *pTimer)
{
    if (pTimer == NULL)
    {
        return ;
    }

    if (pTimer->GetDelFlag())
    {
        return ;
    }

    pTimer->SetDelFlag(true);
    LOG_INFO("remove timer.name:%s, type:%d, param:%s", pTimer->GetName().c_str(), pTimer->GetType(), pTimer->GetParam());
}
